import React,{useState} from 'react'
// 入门
function Sum () {
    const [num, setNum] = useState(0)
    return (
        <div>
            <p>{num}</p>
            <button onClick={() => {setNum(num + 1)}}>add</button>
        </div>
    )
}

// 恢复数据默认值
// 通过一个额外的变量作为默认值，恢复默认值的时候只需要将num 值设置为initial即可

// 解决数据异步问题
const Recover = () => {
    const initial = 0
    const [num, setNum] = useState(initial)
    const handleAdd  = () => {
        // for(let i=0; i< 3; i++) { // 无论循环几次，都仅仅执行一次+ 1.因为react是异步的
        //     setNum(num + 1)
        // }
        for (let i=0; i<3; i++) { // 解决 采用“箭头函数返回值的形式”赋值
            setNum(prevState => prevState +1)
        }
    }
    return (
        <div>
            <p>{num}</p>
            <button onClick={() => {setNum(num + 1)}}>加</button>
            <button onClick={() => {setNum(initial)}}>默认</button>
            <button onClick={() => {setNum(num -1)}}>减</button>
            <button onClick={() => handleAdd()}>解决异步问题</button>
        </div>
    )
}

// 数据类型为Object的修改
function ObjUpdate () {
    const [person, setPerson] = useState({name:'xiaoming',age:18})
    const nameChangeHandle = (e) => {
        console.log(e)
        setPerson({...person, name: e.target.value})
    }
    const ageChangeHandle = (e) => {
        console.log(e.target.value)
        setPerson({...person,age:e.target.value})
    }
    return (
        <div>
            <p>{JSON.stringify(person)}</p>
            <input type="text" value={person.name} onChange={nameChangeHandle}/>
            <input type="number" value={person.age} onChange={ageChangeHandle}/>
        </div>
    )
}

// 数组类型为Array的修改方法
function ArrUpdate () {
    const [str,setStr] = useState('')
    const [arr,setArr] = useState(['math','english'])
    const inputChangeHandle = (e) => {
        setStr(e.target.value)
        console.log(str)
    }
    const addHeadHandle = () => {
        setArr([str,...arr])
        setStr('')
    }
    const addEndHandle = () => {
        setArr([...arr,str])
        setStr('')
    }
    const deleteHeadHandle = () => {
        let new_arr = [...arr]
        new_arr.shift()
        setArr(new_arr)
    }
    const deleteEndHandle = () => {
        let new_arr = [...arr]
        new_arr.pop()
        setArr(new_arr)
    }
    const deleteByIndex = (e) => {
        console.log(e.target.attributes)
        const index = e.target.attributes.index.value
        const new_arr = [...arr]
        new_arr.splice(index,1)
        setArr(new_arr)
    }
    return (
        <div>
            <input type="text" value={str} onChange={inputChangeHandle}/>
            <button onClick={addHeadHandle}>添加头部</button>
            <button onClick={addEndHandle}>添加尾部</button>
            <button onClick={deleteHeadHandle}>删除头部</button>
            <button onClick={deleteEndHandle}>删除尾部</button>
            <ul>
                {
                    arr.map((item,index) => {
                        return <li key={index}>学习 - {index} -{item}<span index={index} onClick={deleteByIndex} style={{cursor:'pointer'}}>删除</span></li>
                    })
                }
            </ul>
        </div>
    )
}

// hooks
// 只能在函数最外层调用 Hook。不要在循环、条件判断或者子函数中调用。
// 只能在 React 的函数组件中调用 Hook。不要在其他 JavaScript 函数中调用。

// 一 useState 笔记
// 解决问题:能够解决类组件所有自定义变量只能存储在this.state的问题
// 基本用法
// useState(value)函数会返回一个数组,该数组包含两个元素,第一个元素为定义的变量,第2个元素为修改该变量对应的函数名称
// 'setVaribale':该名称采用 'set' + '变量名'的驼峰形式命名
// value必填项,不可缺省,值得类型可以是字符串数字数组对象nul;但不可以是undeifned
// setVariable 采用直接异步赋值的形式,并不是像类组件中setState() 那样做异步对比累加赋值

// 性能优化
// 通过React官方文档可以知道，当使用 setXxx 赋值时，Hook会使用Object.is()来对比当前值和新值，结果为true则不渲染，结果为flase就会重新渲染。
// 对于简单类型的值，例如String、Number 新旧值一样的情况下是不会引起重新渲染的
// 对于复杂类型的值，即使新旧值 “看上去是一样的” 也会引起重新渲染。除非新旧值指向同一个对象，或者可以说成新旧值分别是同一个对象的引用；

export default ArrUpdate;
